<?php

namespace App\Func\Order;

use App\ApiCall\Wx\Pay\WxPayExecute;
use App\Enum\GoodsEnum;
use App\Enum\OrderEnum;
use App\Func\User\UserFunc;
use App\Models\Address\AddressModel;
use App\Models\Goods\GoodsModel;
use App\Models\Order\OrderModel;
use App\Models\Order\OrderSubModel;
use Illuminate\Support\Facades\DB;

class OrderFunc
{

    public function getPayConfigBySW($sw){
        switch ($sw){
            case 1:
            default:
                return "default";
        }
    }

    public function getOrderNo($prefix,$payType='wx'){
        $suffix = str_pad(mt_rand(0, 999999), 6, '0', STR_PAD_LEFT); // 6 位随机数作为订单号后缀
        $timestamp = time(); // 当前时间戳
        $date = date("Ymdhis", $timestamp); // 当前日期
        return  "{$payType}{$prefix}{$date}{$timestamp}{$suffix}"; // 组合订单号
    }

    public function createOrder($goodsInfo,$addressId,$config,$prefix,$payType = 'wx'){
        $orderNo = $this->getOrderNo($prefix,$payType);
        $userinfo = (new UserFunc())->getLoginInfo();
        // TODO 这里暂时用的管理员
//        $userinfo = (new CustomerFunc())->getLoginInfo();
        $orderSubModel = (new OrderSubModel());
        $orderModel = (new OrderModel());
        $addressModel = (new AddressModel());
        $goodsModel = (new GoodsModel());
        // 重组goodsIds
        $goodsIds = array_map(function($item) {
            return $item['goods_id'];
        }, $goodsInfo);
        $goodsIdReduceNumbers = array_reduce($goodsInfo, function($result, $item) {
            $result[$item['goods_id']] = $item['goods_number'];
            return $result;
        }, []);
        // 获取所有子订单
        $goodsList = $goodsModel
            ->where(function ($query){
                $query->orWhere('stock_status',GoodsEnum::STOCK_STATUS_1);
                $query->orWhere(function($query){
                    $query->where('stock_status',GoodsEnum::STOCK_STATUS_2);
                    $query->where('stock_start_time','<=',date('Y-m-d h:i:s'));
                });
            })
            ->where('enable_status',1)
            ->where('status',1)
            ->whereIn('goods_id',$goodsIds)
            ->get()
            ->toArray();
        // 检查订单内容和订单是否符合
        if(count($goodsList)!=count($goodsIds)){
            // 处理数组
            $newGoodsIds  = array_map(function($item) {
                return $item['goods_id'];
            }, $goodsList);
            $newGoodsNameId = array_reduce($goodsList, function($result, $item) {
                $result[$item['goods_id']] = $item['goods_name'];
                return $result;
            }, []);
            s_fail_return(null,trans('message.order_err',[
                'name' => "<".$newGoodsNameId[$newGoodsIds[0]].">".trans('key.goods_not_has_stock')
            ]));
        }
        $addressInfo = $addressModel->where('status',1)->where('address_id',$addressId)->first();
        // 校验数据
        if(!$goodsList){
            s_fail_return(null,trans('message.order_err',[
                'name' => 1001
            ]));
        }
        if(!$addressInfo){
            s_fail_return(null,trans('message.order_err',[
                'name' => 1002
            ]));
        }
        // 地址不属于自己
        if($addressInfo['customer_id']!=$userinfo['user_id']){
            s_fail_return(null,trans('message.order_err',[
                'name' => 1003
            ]));
        }


        try {
            DB::beginTransaction();
            $total_amount = 0;
            // 库存检查
            // 10分钟内未支付的订单， 或者已支付的订单
            // 特殊处理订单
            // 添加子订单数据
            $subData = [];
            foreach($goodsList as $goodsInfo){
                $count = $orderModel->where('goods_id',$goodsInfo['goods_id'])->where(function($query){
                    $query->orWhere('pay_status',OrderEnum::PAY_STATUS_1);
                    $query->orWhere(function ($query){
                        $query->where('pay_status',OrderEnum::PAY_STATUS_2)->where('created_at','<=',date('Y-m-d h:i:s',time()-600));
                    });
                })->count();
                if(($goodsInfo['goods_stock']-$count)<$goodsIdReduceNumbers[$goodsInfo['goods_id']]){
                    s_fail_return(null,trans('message.order_err',[
                        'name' => "<".$goodsInfo['goods_name'].">".trans('key.goods_not_has_stock')
                    ]));
                }
                $total_amount += $goodsInfo['goods_price'] * $goodsIdReduceNumbers[$goodsInfo['goods_id']];
                $subData[] = [
                    'goods_id' => $goodsInfo['goods_id'],
                    'product_quantity' => $goodsIdReduceNumbers[$goodsInfo['goods_id']],
                    'product_name' => $goodsInfo['goods_name'],
                    'product_price' => $goodsInfo['goods_price'],
                    'created_at' => date('Y-m-d h:i:s'),
                    'updated_at' => date('Y-m-d h:i:s'),
                ];
            }
            // 计算总价格
            $insertData = [
                'user_id' => $userinfo['user_id'],
                'goods_id' => 0,
                'order_no' => $orderNo,
                'total_amount' => $total_amount,
                'shipping_name' => $addressInfo['recipient_name'],
                'shipping_phone' => $addressInfo['phone_number'],
                'shipping_address' => $addressInfo['state'].'-'.$addressInfo['city'].'-'.$addressInfo['address_line'],
                'order_status' => OrderEnum::ORDER_STATUS_1,
                'pay_status' => OrderEnum::PAY_STATUS_2,
                'created_at' => date('Y-m-d h:i:s'),
                'updated_at' => date('Y-m-d h:i:s'),
            ];
            switch ($payType){
                case 'zfb':
                    $payTypeNumber = OrderEnum::PAY_TYPE_ZFB;
                    break;
                case 'wx':
                default:
                    $payTypeNumber = OrderEnum::PAY_TYPE_WX;
                    switch ($prefix){
                        case 'jsapi':
                            $payCode = (new WxPayExecute($config))->jsApi([]);
                            $payWxMchId = config('openapi.wx.wx_pay.'.$config)['merchantId'];
                            $insertData['wx_pay_order_no'] = $payCode['prepay_id'];
                            $insertData['wx_mch_id'] = $payWxMchId;
                            break;
                        default:
                            s_fail_return(null,trans('message.order_err',[
                                'name' => trans('key.prefix_err')
                            ]));
                    }
                    break;
            }
            $insertData['pay_type'] = $payTypeNumber;
            $id =  $orderModel->insertGetId($insertData);
            // 获取到主订单以后 添加子表信息
            foreach($subData as $key => $sub){
                $subData[$key]['order_id'] = $id;
            }
            $orderSubModel->insert($subData);
            DB::commit();
            return $id;
        }catch (\Exception $exception){
            DB::rollBack();
            s_fail_return(null,trans('message.order_err',[
                'name' => 1004
            ]));
        }
    }
}
